package org.mushroomdb.lock;

import java.util.Iterator;

import org.mushroomdb.catalog.Register;
import org.mushroomdb.catalog.Table;
import org.mushroomdb.exception.RDBMSRuntimeException;
import org.mushroomdb.interceptor.AbstractInterceptor;
import org.mushroomdb.lock.locktypes.Lock;
import org.mushroomdb.security.SecurityService;
import org.mushroomdb.security.User;
import org.mushroomdb.service.ServiceManager;

/**
 * @author Tomas
 *
 * Checks if the resource is lockFree
 */
public class LockInterceptor extends AbstractInterceptor {
    
    
    public void beforeInsert(Register register, Table table) {
        if(isLocked(table)){
            throw new RDBMSRuntimeException(new LockException ("LA tabla esta lockeada por otro usuario" ));
        }
        
                
    }
    
    public void beforeUpdate(Register register, int columnIndex, Object value,Table table) {
        
        if(isLocked(register)){
            throw new RDBMSRuntimeException(new LockException ("Hay registros lockeados por otro usuario" ));
        }
    }
         
    public void beforeDelete(Register register, Table table) {
        //TODO hacer validacion a nivel de Tabla
        if(isLocked(register)){
            throw new RDBMSRuntimeException(new LockException ("Hay registros lockeados por otro usuario" ));
        }
    }
        
    public void beforeCreate(Table table) {
        //TODO Implementar
        
    }
        
    public void beforeDrop(Table table) {
        //TODO implementar
    }
    
    private boolean isLocked(Register register){
        LockService lockService = (LockService) ServiceManager.getInstance().getService(LockService.class);
        Iterator iter = lockService.getLocks(register);
        
        SecurityService securityService = (SecurityService) ServiceManager.getInstance().getService(SecurityService.class);
        User user = securityService.getUserFromContext();
        
        while(iter.hasNext()){
            Lock lock = (Lock)iter.next();
            
            if( !lock.getUserId().equals(user.getName())){
                return true;
            }
        }
        return false;
     }
    
    private boolean isLocked(Table table){
        LockService lockService = (LockService) ServiceManager.getInstance().getService(LockService.class);
        Iterator iter = lockService.getLocks(table);
        
        SecurityService securityService = (SecurityService) ServiceManager.getInstance().getService(SecurityService.class);
        User user = securityService.getUserFromContext();
        
        while(iter.hasNext()){
            Lock lock = (Lock)iter.next();
            
            if( !lock.getUserId().equals(user.getName())){
                return true;
            }
        }
        return false;
     }
        
        
    
    
    
}
